
#ifndef _MEMBER_BCLASS_H_
#define _MEMBER_BCLASS_H_

#include <BMap>
#include <BClass>

#define class_member(cls)	((member_BClass*)((BClass*)cls)->_ptr)

namespace BWE
{
	class BScript;

	struct VariantInfo
	{
		inline VariantInfo()
		{
			access = BClass::Access_None;
		}
		inline bool operator == (const BString& name) const
		{
			return this->name == name;
		}
		inline bool operator != (const BString& name) const
		{
			return this->name != name;
		}
		bool			cnst = false;
		BString			type;
		BString			name;
		BValue			value;
		BClass::Access	access;
	};

	struct ParamInfo
	{
		inline ParamInfo()
		{
			cnst = false;
			refe = 0;
			defut = false;
		}
		inline ParamInfo(const BString& text)
		{
			cnst = false;
			refe = 0;
			defut = false;
			this->type = text;
			if (type.beginWith("const "))
			{
				type.remove("const ");
				cnst = true;
			}
			if (type.endWith('&') || type.endWith('*'))
			{
				refe = type.last();
				type -= refe;
			}
		}
		bool			cnst;
		char			refe;
		bool			defut;
		BString			type;
		BString			name;
		BValue			value;
	};
	typedef BArray<ParamInfo>	ParamInfoArray;

	class MethodInfo : public BThing
	{
	public:
		inline MethodInfo(BClass* cls)
		{
			line = -1;
			meta = cls->isMeta();
			virt = false;
			cnst = false;
			access = BClass::Access_None;
		}
		inline MethodInfo(const MethodInfo& other)
		{
			line = other.line;
			meta = other.meta;
			virt = other.virt;
			cnst = other.cnst;
			type = other.type;
			name = other.name;
			method = other.method;
			params = other.params;
			access = other.access;
		}
		int					line;
		bool				meta;
		bool				virt;
		bool				cnst;
		BString				type;
		BString				name;
		BValue				method;
		BArray<ParamInfo>	params;
		BClass::Access		access;
	};
	typedef BHolder<MethodInfo>			MethodInfoHolder;
	typedef BArray<MethodInfoHolder>	MethodInfoHolderArray;

	bool AnalyseDeclare(BString& name, BString& type, ParamInfoArray& params);
	bool AnalyseParam(BString& word, ParamInfo& pinfo);
	bool CreateValue(BString& word, ParamInfo& pinfo);
	bool ValueString(BString& text, const BValue& value);

	class member_BClass
	{
	public:
		member_BClass(BClass* cls);
		~member_BClass();

		bool instantiate(const BString& name);
		bool checkInherit(const BString& type);
		VariantInfo* findVariant(const BString& name);
		BValue* findValue(const BString& path);

		BClass*					boss;
		BScript*				script;
		bool					ismeta;
		BStringArray			tempTypes;
		BExpHolderArray			inherits;
		BExpHolderArray			declares;
		BArray<VariantInfo>		variants;
		BMap<BString, MethodInfoHolder>	methodMap;
	};

}

#endif